package com.example.java2024_5_1searcher.searcher;

import java.io.*;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//读取并解析文档
public class Parser {
    //首先递归目录，留下html文件，
    static ArrayList<File> html = new ArrayList<>();
    static String OLD_PATH =null;
    static {
        if(Flag.flag){
            OLD_PATH = "E:\\java_jdk\\jdk-8u411-docs-all\\docs\\api";
        }else {
            OLD_PATH ="/root/do_searcher/api";
        }

    }
    private static final String NEW_PATH = "https://docs.oracle.com/javase/8/docs/api";
    Index index = new Index();
//普通构建索引方法
    public void zhu() {
        File files = new File(OLD_PATH);
        dohtml(files, html);
        //解析完获得所有文件获取所有html文件后，解析标题，正文，以及url
        for (File file : html) {
            token(file);
        }
        index.save();

    }
//多线程构建索引方法
public  void thread_zhu() throws InterruptedException {
    File files = new File(OLD_PATH);
    dohtml(files, html);
   //利用一个计数的类每一个html解析完成后加1
    CountDownLatch latch = new CountDownLatch(html.size());
    // 2. 循环遍历文件. 此处为了能够通过多线程制作索引, 就直接引入线程池.
    ExecutorService executorService = Executors.newFixedThreadPool(8);
    for (File f : html) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("解析 " + f.getAbsolutePath());
                token(f);
                latch.countDown();
            }
        });
    }
    // await 方法会阻塞, 直到所有的选手都调用 countDown 撞线之后, 才能阻塞结束.
    latch.await();
    // 手动的把线程池里面的线程都干掉!
    executorService.shutdown();
    // 3. 保存索引
    index.save();
}

    public void dohtml(File files, ArrayList<File> html) {
        for (File file : files.listFiles()) {
            if (file.isDirectory()) {
                dohtml(file, html);
            }
            if (file.getName().contains(".html")) {
                html.add(file);
            }
        }
    }

    public void token(File file) {
        //解析标题(文件名减去.html)
        String title = title(file);
        //解析正文,读取文件内容
        String text = textmax(file);
        //解析url(本地文档和线上文档只有前面的前缀不同,将本地前面的部分替换线上就得到了线上的)
        String url = url(file);
        //将解析结果传给index类构建正排索引，倒排索引
        index.addDoc(title, text, url);
    }

    public String title(File file) {
        return file.getName().substring(0, file.getName().length() - ".html".length());
    }

    public String textmax(File file) {
        String text = text(file);
        //去掉js代码
        text=text.replaceAll("<script[^>]*>.*?</script>", " ");
        //如果是html代码，+？非贪婪匹配
        text=text.replaceAll("<.*?>", " ");
        //这样会产生很多的空格,将多个空格合并为一个\\s表示一个或多个空格？表示0或多个
       text=text.replaceAll("\\s+", " ");
        return text;

    }

    public String text(File file) {
        //从文件中读取
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
            StringBuilder stringBuilder = new StringBuilder();
            while (true) {
                int ret = bufferedReader.read();
                if (ret == -1) {
                    break;
                }
                char ch = (char) ret;
                if (ch == '\r' || ch == '\n') {
                    stringBuilder.append(' ');
                    continue;
                }
                stringBuilder.append(ch);
            }
            return stringBuilder.toString();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String url(File file) {
        return file.getAbsolutePath().replace(OLD_PATH, NEW_PATH);

    }

    public static void main(String[] args) throws InterruptedException {
        Index index1 = new Index();
        Parser parser = new Parser();
        parser.thread_zhu();
///
//        for (File file : html) {
//            System.out.println(file);
//        }
    }


}